import std.algorithm.searching;
import std.conv;
import std.experimental.logger.core;
import std.string;
import std.traits;

private __gshared string[string] _items_string;
private __gshared ushort[string] _items_ushort;

const string[] mandatory_items_string = ["type", "rotors", "rings", "reflector", "listen", "remote", "keyfile"];
const string[] mandatory_items_ushort = ["port", "rport", "timeout", "powleadingzero", "powfirstbytemax"];

const string[] values_ushort = mandatory_items_ushort ~ ["powlife", "idletimeout"];

void readConfig(string config)
{
	string key, val;
	long pos;
	foreach (line; config.lineSplitter())
	{
		if (strip(line) == "")
		{
			continue;
		}
		pos = line.indexOf('=');
		if (pos == -1)
		{
			continue;
		}
		key = strip(line[0 .. pos]);
		val = strip(line[pos+1 .. line.length]);
		if (key == "" || val == "")
		{
			continue;
		}

		if (canFind(values_ushort, key))
		{
			try
			{
				_items_ushort[key] = to!ushort(val);
			}
			catch (ConvException)
			{
				fatal("Could not convert " ~ key ~ " to ushort");
			}
		}
		else
		{
			_items_string[key] = val;
		}
	}
}

void validateConfig()
{
	foreach (string item; mandatory_items_string)
	{
		if ((item in _items_string) is null)
		{
			fatal("Missing item: " ~ item);
		}
	}

	foreach (string item; mandatory_items_ushort)
	{
		if ((item in _items_ushort) is null)
		{
			fatal("Missing item: " ~ item);
		}
	}
}

string getString(string key)
{
	auto ptr = (key in _items_string);

	if (ptr is null)
	{
		return null;
	}
	else
	{
		return *ptr;
	}
}

ushort getUnsignedShort(string key)
{
	auto ptr = (key in _items_ushort);

	if (ptr is null)
	{
		return 0;
	}
	else
	{
		return *ptr;
	}
}